package com.ry;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 野狗菌
 * 2020-04-06
 * 爬虫入门（一）：获取网页源代码，爬取手机号码
 * 微信公众号：希望你能喜欢   （也可以搜索   foryouway   ）
 * 个人网站：www.wayteam.xyz
 */
public class GetPhoneNumber {

    public static void main(String[] args) throws Exception {

        //创建一个要访问的url
        URL url = new URL("https://s.taobao.com/search?q=%E5%A5%B6%E5%98%B4&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.21814703.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306");//这里以我的博客测试页面为例

        System.out.println("正在获取"+url+"网站的手机号码中-----请稍等");//无关紧要的代码，只是为了友好的提示

        //打开上面获取的链接
        URLConnection urlConnection = url.openConnection();  //新手提醒：这个会抛出异常，我为了方便，全部抛出去，不作处理throws Exception

        //创建一个指定的存储文件
        File file = new File("phone.txt"); //这里是相对路径，表示存在这个同级目录下
        //创建一个字符输出流（从本程序输出到phone.txt文件）
        PrintWriter printWriter = new PrintWriter(file);//程序执行到这里就会在对应位置创建对应文件了

        //创建一个输入流（这个输入输出是以本程序为参照）
        InputStream inputStream = urlConnection.getInputStream();

        //把上面的字节流转化为字符流
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

        //把字符流转化为字符缓冲流
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

        //创建一个空的字符串来接收从字符缓冲流里接收的数据
        String htmlLine = null;

        //手机号码的正则表达式，用来匹配数据中的手机号码
        String regex = "1[35789]\\d{9}";//1：第一位是1，[35789]:第二位是35789中的一个，\d{9}:剩余9位数任意（因为java中\需要转义，所以这里用\\)。
        Pattern pattern = Pattern.compile(regex);//把正则表达式编译成模式。

        //用while遍历上面的到的字缓冲流，把值给上面的空字符串（readLine是一行一行读取网页源代码的）
        while ((htmlLine = bufferedReader.readLine()) != null){  //当字符流缓冲流没有为空时，一直读取它。

            //创建一个匹配器来匹配上面的正则表达式模式
            Matcher matcher = pattern.matcher(htmlLine);

            //循环匹配
            while (matcher.find()){  //当匹配成功时，往下执行
                printWriter.println(matcher.group());//将匹配的数据用group转化为字符串，写进字符输出流中
            }

            /**
             * 在控制台打印htmlLine,观察它是什么样的数据
             * 为了方便大家理解readLine执行过程，给进程设置一个休眠时间，不然数据哗啦一下直接出来
             * 这里我录制了一个动图，大家也可以自己试试。
             */
            /*System.out.println(htmlLine);
            Thread.sleep(100);//100毫秒*/

        }

        /**
         * 关闭这两个流
         */
        bufferedReader.close();
        printWriter.close();

        System.out.println("获取号码成功，快去"+file+"查看结果吧"+"\n"+"-------by野狗菌\uD83D\uDC36");//无关紧要的代码，只是为了友好的提示
    }

}